home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / mh / mh-6.8 / support / pop / popauth.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-12-14  |  5.6 KB  |  252 lines

  1. /* popauth.c - manipulate POP authorization DB */
  2. #ifndef    lint
  3. static char ident[] = "@(#)$Id: popauth.c,v 1.7 1992/12/15 00:20:22 jromine Exp $";
  4. #endif    /* lint */
  5.  
  6. #include "../h/mh.h"
  7. #include "popauth.h"
  8. #undef    DBM        /* used by mts.c and ndbm.h */
  9. #include <ndbm.h>
  10. #include <pwd.h>
  11. #include <stdio.h>
  12. #include <sys/types.h>
  13. #include <sys/stat.h>
  14. #include <sys/file.h>
  15. #ifdef    SYS5
  16. #include <fcntl.h>
  17. #endif
  18. #include "../zotnet/bboards.h"
  19. #include "../zotnet/mts.h"
  20.  
  21. /*   */
  22.  
  23. static struct swit switches[] = {
  24. #define    INITSW    0
  25.     "init", 0,
  26. #define    LISTSW    1
  27.     "list", 0,
  28. #define    USERSW    2
  29.     "user name", 0,
  30.  
  31. #define    HELPSW    3
  32.     "help", 4,
  33.  
  34.     NULL, 0
  35. };
  36.  
  37. /*   */
  38.  
  39. char   *getpass ();
  40.  
  41. /*   */
  42.  
  43. /* ARGSUSED */
  44.  
  45. main (argc, argv)
  46. int    argc;
  47. char   *argv[];
  48. {
  49.     int        flags,
  50.         i,
  51.         initsw = 0,
  52.         insist,
  53.         listsw = 0;
  54.     long    clock;
  55.     char   *bp,
  56.        *cp,
  57.        *usersw = NULL,
  58.         buf[100],
  59.       **ap,
  60.       **argp,
  61.        *arguments[MAXARGS];
  62.     datum   key,
  63.         value;
  64.     DBM    *db;
  65.     struct authinfo auth;
  66.  
  67.     invo_name = r1bindex (argv[0], '/');
  68.     m_foil (NULLCP);
  69.     if ((cp = m_find (invo_name)) != NULL) {
  70.     ap = brkstring (cp = getcpy (cp), " ", "\n");
  71.     ap = copyip (ap, arguments);
  72.     }
  73.     else
  74.     ap = arguments;
  75.     (void) copyip (argv + 1, ap);
  76.     argp = arguments;
  77.  
  78. /*   */
  79.  
  80.     while (cp = *argp++) {
  81.     if (*cp == '-')
  82.         switch (smatch (++cp, switches)) {
  83.         case AMBIGSW: 
  84.             ambigsw (cp, switches);
  85.             done (1);
  86.         case UNKWNSW: 
  87.             adios (NULLCP, "-%s unknown", cp);
  88.         case HELPSW: 
  89.             (void) sprintf (buf, "%s [switches]", invo_name);
  90.             help (buf, switches);
  91.             done (1);
  92.  
  93.         case INITSW:
  94.             initsw = 1, listsw = 0;
  95.             continue;
  96.         case LISTSW:
  97.             listsw = 1, initsw = 0;
  98.             continue;
  99.         case USERSW:
  100.             if (!(usersw = *argp++) || *usersw == '-')
  101.             adios (NULLCP, "missing argument to %s", argp[-2]);
  102.             continue;
  103.         }
  104.     adios (NULLCP, "usage: %s [switches]", invo_name);
  105.     }
  106.  
  107. /*   */
  108.  
  109. #ifndef    APOP
  110.     adios (NULLCP, "not compiled with APOP option");
  111. #else
  112.     if (getuid ())
  113.     initsw = listsw = 0, usersw = NULL;
  114.  
  115.     if (initsw) {
  116.     struct passwd *pw;
  117.     struct stat st;
  118.  
  119.     if ((pw = getpwnam (POPUID)) == NULL)
  120.         adios (NULLCP, "POP user-id unknown");
  121.  
  122.     (void) sprintf (buf, "%s.dir", APOP);
  123.     if (stat (buf, &st) != NOTOK) {
  124.         if (!getanswer ("Really initialize POP authorization DB? "))
  125.         done (1);
  126.         (void) unlink (buf);
  127.         (void) sprintf (buf, "%s.pag", APOP);        
  128.         (void) unlink (buf);
  129.     }
  130.     if ((db = dbm_open (APOP, O_RDWR | O_CREAT, 0600)) == NULL)
  131.         adios (APOP, "unable to create POP authorization DB");
  132.     if (fchown (dbm_dirfno (db), pw -> pw_uid, pw -> pw_gid) == NOTOK
  133.             || fchown (dbm_pagfno (db), pw -> pw_uid, pw -> pw_gid)
  134.                 == NOTOK)
  135.         advise (" ", "error setting ownership of POP authorization DB");
  136.  
  137.     done (0);
  138.     }
  139.  
  140.     if ((db = dbm_open (APOP, O_RDONLY, 0)) == NULL)
  141.     adios (APOP, "unable to open POP authorization DB");
  142.  
  143.     if (flock (dbm_pagfno (db), LOCK_SH) == NOTOK)
  144.     adios (APOP, "unable to lock POP authorization DB");
  145.  
  146.     if (listsw) {
  147.     if (usersw) {
  148.         key.dsize = strlen (key.dptr = usersw) + 1;
  149.         value = dbm_fetch (db, key);
  150.         if (value.dptr == NULL)
  151.         adios (NULLCP, "no such entry in POP authorization DB");
  152.         bcopy (value.dptr, (char *) &auth, sizeof auth);
  153.         printf ("%s\n", key.dptr);
  154.     }
  155.     else
  156.         for (key = dbm_firstkey (db); key.dptr; key = dbm_nextkey (db)) {
  157.         printf ("%s", key.dptr);
  158.         value = dbm_fetch (db, key);
  159.         if (value.dptr == NULL)
  160.             printf (" - no information?!?\n");
  161.         else {
  162.             bcopy (value.dptr, (char *) &auth, sizeof auth);
  163.             printf ("\n");
  164.         }
  165.         }
  166.  
  167.     dbm_close (db);
  168.  
  169.     done (0);
  170.     }
  171.  
  172.     if (usersw == NULL)
  173.     usersw = getusr ();
  174.  
  175.     fprintf (stderr, "Changing POP password for %s.\n", usersw);
  176.  
  177.     key.dsize = strlen (key.dptr = usersw) + 1;
  178.     value = dbm_fetch (db, key);
  179.     if (value.dptr != NULL) {
  180.     bcopy (value.dptr, (char *) &auth, sizeof auth);
  181.     dbm_close (db);
  182.  
  183.     if ((i = strlen (strcpy (buf, getpass ("Old password:")))) == 0
  184.             || auth.auth_secretlen != i
  185.             || bcmp (buf, auth.auth_secret, i))
  186.         fprintf (stderr, "Sorry.\n"), exit (1);
  187.     }
  188.     else
  189.     dbm_close (db);
  190.  
  191. #ifdef    lint
  192.     flags = 0;
  193. #endif    /* lint */
  194.     for (insist = 0; insist < 2; insist++) {
  195.     int    i;
  196.     char    c;
  197.  
  198.     if (insist)
  199.         printf ("Please use %s.\n",
  200.             flags == 1 ? "at least one non-numeric character"
  201.             : "a longer password");
  202.  
  203.     if ((i = strlen (strcpy (buf, getpass ("New password:")))) == 0) {
  204.         fprintf (stderr, "Password unchanged.\n");
  205.         exit (1);
  206.     }
  207.  
  208.     flags = 0;
  209.     for (cp = buf; c = *cp++;)
  210.         if (c >= 'a' && c <= 'z')
  211.         flags |= 2;
  212.         else
  213.         if (c >= 'A' && c <= 'Z')
  214.             flags |= 4;
  215.         else
  216.             if (c >= '0' && c <= '9')
  217.             flags |= 1;
  218.             else
  219.             flags |= 8;
  220.  
  221.     if ((flags >= 7 && i >= 4)
  222.         || ((flags == 2 || flags == 4) && i >= 6)
  223.         || ((flags == 3 || flags == 5 || flags == 6) && i >= 5))
  224.         break;
  225.     }
  226.  
  227.     if (strcmp (buf, getpass ("Retype new password:"))) {
  228.     fprintf (stderr, "Mismatch - password unchanged.\n");
  229.     exit (1);
  230.     }
  231.  
  232.     if ((db = dbm_open (APOP, O_RDWR, 0)) == NULL)
  233.     adios (APOP, "unable to open POP authorization DB");
  234.  
  235.     if (flock (dbm_pagfno (db), LOCK_EX) == NOTOK)
  236.     adios (APOP, "unable to lock POP authorization DB");
  237.  
  238.     key.dsize = strlen (key.dptr = usersw) + 1;
  239.  
  240.     buf[sizeof auth.auth_secret] = NULL;
  241.     bcopy (buf, auth.auth_secret, auth.auth_secretlen = strlen (buf));
  242.     value.dptr = (char *) &auth, value.dsize = sizeof auth;
  243.  
  244.     if (dbm_store (db, key, value, DBM_REPLACE))
  245.     adios (NULLCP, "POP authorization DB may be corrupt?!?");
  246.     dbm_close (db);
  247. #endif
  248.  
  249.     done (0);
  250.     /* NOTREACHED */
  251. }
  252.